local L = AceLibrary("AceLocale-2.2"):new("QuestAnnouncer")

local CHATTYPE ="SAY"

local EPA_TestPatterns =
{
	-- L["FQ_EPA_PATTERN1"],
	-- L["FQ_EPA_PATTERN2"],
	-- L["FQ_EPA_PATTERN3"],
	-- L["FQ_EPA_PATTERN4"],
	-- L["FQ_EPA_PATTERN5"],
	-- L["FQ_EPA_PATTERN6"],
	L["FQ_EPA_PATTERN7"],
};

local options = {
	type = 'group',
	args = {
		debug = {
			type = 'toggle',
			name = L["OPT_SHOWDEBUG_NAME"],
			desc = L["OPT_SHOWDEBUG_DESC"],
			get = "IsShowDebug",
			set = "ToggleShowDebug",
		},
		announce = {
			type = 'text',
			name = L["OPT_ANNOUNCE_NAME"],
			desc = L["OPT_ANNOUNCE_DESC"],
			get = "GetAnnounceType",
			set = "SetAnnounceType",
			validate = { "addon", "chat", "both", "none" },
		},
		display = {
			type = 'text',
			name = L["OPT_DISPLAY_NAME"],
			desc = L["OPT_DISPLAY_DESC"],
			get = "GetDisplayType",
			set = "SetDisplayType",
			validate = { "ui", "chat", "both", "none" },
		},
		progress = {
			type = 'text',
			name = L["OPT_PROGRESS_NAME"],
			desc = L["OPT_PROGRESS_DESC"],
			get = "GetProgressType",
			set = "SetProgressType",
			validate = { "all", "last" },
		},
	},
}

QuestAnnouncer = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0", "AceEvent-2.0", "AceDB-2.0" )
QuestAnnouncer:RegisterChatCommand( {L["SLASHCMD_LONG"], L["SLASHCMD_SHORT"]}, options )
QuestAnnouncer:RegisterDB( "QuestAnnouncerDB", "QuestAnnouncerDBPC" )
QuestAnnouncer:RegisterDefaults( "profile", {
	showDebug = false,
	announcet = "addon",
	displayt = "both",
	progresst = "last",
} )

function QuestAnnouncer:OnEnable()
	self:RegisterEvent("CHAT_MSG_ADDON")
	self:RegisterEvent("UI_INFO_MESSAGE")
    self:RegisterEvent("CHAT_MSG_SYSTEM")
end

function QuestAnnouncer:CHAT_MSG_ADDON( prefix, message, mode, sender )
	if (prefix == L["ADDON_PREFIX"]) and (message ~= nil) and (mode == "PARTY") and (sender ~= UnitName("player")) then
		if (self:GetDisplayType() == "ui") or (self:GetDisplayType() == "both") then
			UIErrorsFrame:AddMessage(sender..": |cffFFFF00任务进度：|r"..message,0.75,1.0,0.5,1.0,UIERRORS_HOLD_TIME)
		end
		if (self:GetDisplayType() == "chat") or (self:GetDisplayType() == "both") then
			
			self:Print(sender..": |cffFFFF00任务进度：|r"..message)
		end
	end
end

function QuestAnnouncer:GetColor(min, max)
    max = max or 1
    min = min or max or 1

    local perc = min / max
    local r1, g1, b1, r2, g2, b2
    if perc <= 0.5 then
        perc = perc * 2
        r1, g1, b1 = 1, 0, 0
        r2, g2, b2 = 1, 1, 0
    else
        perc = perc * 2 - 1
        r1, g1, b1 = 1, 1, 0
        r2, g2, b2 = 0, 1, 0
    end
    local r = r1 + (r2 - r1) * perc
    local g = g1 + (g2 - g1) * perc
    local b = b1 + (b2 - b1) * perc

    return r, g, b
end

function QuestAnnouncer:UI_INFO_MESSAGE( message )
	-- -- does the message fits our schema?
	-- local questUpdateText = gsub(message,"(.*):%s*([-%d]+)%s*/%s*([-%d]+)%s*$","%1",1)
	-- if (questUpdateText ~= message) then
		local outmessage
		local ii, jj, strItemName, iNumItems, iNumNeeded = string.find(message, "(.*)：%s*([-%d]+)%s*/%s*([-%d]+)%s*$")
																			-- "([%w%u%a]*)[:：]%s*([-%d]+)%s*/%s*([-%d]+)%s*$"
		if strItemName then
		local stillneeded = iNumNeeded-iNumItems

		local r, g, b = self:GetColor(iNumItems, iNumNeeded)
		local lootColor = string.format("|cff%02x%02x%02x", r * 255, g * 255, b * 255)
		if stillneeded < 1  and ((self:GetProgressType() == "last") or (self:GetProgressType() == "all")) then
			outmessage = "|cffffffff" .. strItemName .. " " .. lootColor .. iNumItems .. "/" .. iNumNeeded .. " |cffFFFF00 已完成|r"
			-- outmessage=L["FINMSG"];
			-- outmessage=string.gsub(outmessage,"$LootColor",lootColor)
			-- outmessage=string.gsub(outmessage,"$NumItems",iNumItems)
			-- outmessage=string.gsub(outmessage,"$NumNeeded",iNumNeeded)
			-- outmessage=string.gsub(outmessage,"$ItemName",strItemName)
			-- outmessage=string.gsub(outmessage,"$NumLeft",stillneeded)
		end
		if stillneeded > 0 and (self:GetProgressType() == "all") then
			outmessage = "|cffffffff" .. strItemName .. " " .. lootColor .. iNumItems .. "/" .. iNumNeeded .. "|r"
			-- outmessage=L["ADVMSG"]
			-- outmessage=string.gsub(outmessage,"$LootColor",lootColor)
			-- outmessage=string.gsub(outmessage,"$NumItems",iNumItems)
			-- outmessage=string.gsub(outmessage,"$NumNeeded",iNumNeeded)
			-- outmessage=string.gsub(outmessage,"$ItemName",strItemName)
			-- outmessage=string.gsub(outmessage,"$NumLeft",stillneeded)
		end

		if self:IsShowDebug() then
			self:Print(outmessage)
		end
		if (GetNumPartyMembers()>0) and (outmessage ~= nil) and ((self:GetAnnounceType() == "chat") or (self:GetAnnounceType() == "both")) then
			SendChatMessage("|cffFFFF00任务进度：|r" .. outmessage, "PARTY")
		end
		if (GetNumPartyMembers()>0) and (outmessage ~= nil) and ((self:GetAnnounceType() == "addon") or (self:GetAnnounceType() == "both")) then
			SendAddonMessage(L["ADDON_PREFIX"], outmessage, "PARTY")
		end
	end
end

function QuestAnnouncer:CHAT_MSG_SYSTEM( message )
    for index, value in EPA_TestPatterns do
		if ( string.find(message, value) ) then
            if self:IsShowDebug() then
                self:Print(message)
            end
            if (GetNumPartyMembers()>0) and (message ~= nil) and (self:GetAnnounceType() == "chat") or (self:GetAnnounceType() == "both") then
                SendChatMessage(message, "PARTY")
            end
            if (GetNumPartyMembers()>0) and (message ~= nil) and ((self:GetAnnounceType() == "addon") or (self:GetAnnounceType() == "both")) then
                SendAddonMessage(L["ADDON_PREFIX"], message, "PARTY")
            end
			break;
		end
	end
end

function QuestAnnouncer:IsShowDebug()
	return self.db.profile.showDebug
end

function QuestAnnouncer:ToggleShowDebug()
	self.db.profile.showDebug = not self.db.profile.showDebug
	if self.db.profile.showDebug then
		self:Print(L["OPT_SHOWDEBUG_ON"])
	else
		self:Print(L["OPT_SHOWDEBUG_OFF"])
	end
end

function QuestAnnouncer:GetAnnounceType()
	return self.db.profile.announcet
end

function QuestAnnouncer:SetAnnounceType(name)
	self.db.profile.announcet = name
	if name == "addon" then
		self:Print(L["OPT_ANNOUNCE_ADDON"])
	elseif name == "chat" then
		self:Print(L["OPT_ANNOUNCE_CHAT"])
	elseif name == "both" then
		self:Print(L["OPT_ANNOUNCE_BOTH"])
	elseif name == "none" then
		self:Print(L["OPT_ANNOUNCE_NONE"])
	end
end

function QuestAnnouncer:GetDisplayType()
	return self.db.profile.displayt
end

function QuestAnnouncer:SetDisplayType(name)
	self.db.profile.displayt = name
	if name == "ui" then
		self:Print(L["OPT_DISPLAY_UI"])
	elseif name == "chat" then
		self:Print(L["OPT_DISPLAY_CHAT"])
	elseif name == "both" then
		self:Print(L["OPT_DISPLAY_BOTH"])
	elseif name == "none" then
		self:Print(L["OPT_DISPLAY_NONE"])
	end
end

function QuestAnnouncer:CheckDefaultChat()
	if ChatFrameEditBox:IsVisible() then
		CHATTYPE = ChatFrameEditBox.chatType
		return
	end
	if (GetNumPartyMembers() == 0) then
			CHATTYPE = "SAY";
	else
		if (GetNumRaidMembers() > 0) then
			CHATTYPE = "RAID";
		else
			CHATTYPE = "PARTY";
		end
	end
end

function QuestAnnouncer:GetProgressType()
	return self.db.profile.progresst
end

function QuestAnnouncer:SetProgressType(name)
	self.db.profile.progresst = name
	if name == "all" then
		self:Print(L["OPT_PROGRESS_ALL"])
	elseif name == "last" then
		self:Print(L["OPT_PROGRESS_LAST"])
	end
end

function QuestAnnouncer:StripText(text)
	if not text then return end
	text = string.gsub(text, '|c%x%x%x%x%x%x%x%x(.-)|r', '%1')
	text = string.gsub(text, '%[.*%]%s*', '')
	text = string.gsub(text, '(.+) %(.+%)', '%1')
	return text
end

local hexcolor_cache = {}
local function rgbhex(r, g, b, a)
  local key
  if type(r)=="table" then
    local _r,_g,_b,_a
    if r.r then
      _r,_g,_b,_a = r.r, r.g, r.b, r.a or 1
    elseif table.getn(r) >= 3 then
      _r,_g,_b,_a = r[1], r[2], r[3], r[4] or 1
    end
    if _r and _g and _b and _a then
      key = string.format("%s%s%s%s",_r,_g,_b,_a)
      if hexcolor_cache[key] == nil then
        hexcolor_cache[key] = string.format("|c%02x%02x%02x%02x", _a*255, _r*255, _g*255, _b*255)
      end
    end
  elseif tonumber(r) and g and b then
    a = a or 1
    key = string.format("%s%s%s%s",r,g,b,a)
    if hexcolor_cache[key] == nil then
      hexcolor_cache[key] = string.format("|c%02x%02x%02x%02x", a*255, r*255, g*255, b*255)
    end
  end
  return hexcolor_cache[key] or ""
end

function QuestLogTitleButton_OnClick(button)
	local scrollFrame = EQL3_QuestLogListScrollFrame or ShaguQuest_QuestLogListScrollFrame or QuestLogListScrollFrame
	local qIndex = this:GetID() + FauxScrollFrame_GetOffset(scrollFrame)
	local qTitle, qLevel, qTag, isHeader, isCollapsed = GetQuestLogTitle(qIndex);
	qTitle = QuestAnnouncer:StripText(qTitle)
    
	if (button == "LeftButton") then
		QuestLog_SetSelection(qIndex);
        QuestLog_Update()
		if (IsShiftKeyDown() and ChatFrameEditBox:IsVisible() and not isHeader) then
			if pfQuest and pfQuest_config["questlinks"] == "1" then
				local questids = pfDatabase:GetQuestIDs(qIndex)
				local questid = questids and tonumber(questids[1]) or 0
				local hex = rgbhex(GetDifficultyColor(qLevel))
				ChatFrameEditBox:Insert(hex .. "|Hquest:" .. questid .. ":" .. qLevel .. "|h[" .. qTitle .. "]|h|r")
				QuestLog_Update()
			else
				if (qTag) then qTag = (" (" .. qTag .. ")  ") else qTag = ""; end
				ChatFrameEditBox:Insert("[" .. qLevel .. "] " .. qTitle .. qTag);
			end
		elseif (IsShiftKeyDown()) then
			if (qIndex) then
				if (IsQuestWatched(qIndex)) then
					RemoveQuestWatch(qIndex);
					QuestLog_Update();
					QuestWatch_Update();
				else
					AddQuestWatch(qIndex);
					QuestLog_Update();
					QuestWatch_Update();
				end
			end
		elseif (IsControlKeyDown()) then
			QuestAnnouncer:CheckDefaultChat();
			if (qTag) then qTag = (" (" .. qTag .. ")  ") else qTag = ""; end
				SendChatMessage("[" .. qLevel .. "] " .. qTitle .. qTag, CHATTYPE, GetDefaultLanguage());
			local nObjectives = GetNumQuestLeaderBoards(qIndex);
			if (nObjectives > 0) then
				for i = 1, nObjectives do
					oText, oType, oDone = GetQuestLogLeaderBoard(i, qIndex);
					if (not oText or strlen(oText) == 0 or oText == "") then oText = oType; end
					if (oDone) then
						SendChatMessage("  X " .. oText, CHATTYPE);
					else
						SendChatMessage("  -  " .. oText, CHATTYPE);
					end
				end
			end
		end
	elseif (button == "RightButton") then
		if (IsControlKeyDown()) then
			QuestLog_SetSelection(qIndex);
            QuestLog_Update()
			local qDescription, qObjectives = GetQuestLogQuestText();
			QuestAnnouncer:CheckDefaultChat();
			if (qObjectives) then
				if (qTag) then qTag = (" (" .. qTag .. ")  ") else qTag = ""; end
					SendChatMessage("[" .. qLevel .. "] " .. qTitle .. qTag .. ": " .. qObjectives, CHATTYPE, GetDefaultLanguage());
			end
			return;
		end
	end
end